package com.example.admin.scheduler;

import com.example.admin.mapper.SchedulerXMapper;
import com.example.admin.model.TaskDisp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;

@Component
public class SchedulerX2 {

    private static final Logger logger = LoggerFactory.getLogger(SchedulerX2.class);

    //数据库的任务
    public static ConcurrentHashMap<String, TaskDisp> tasks = new ConcurrentHashMap<>(10);

    //正在运行的任务
    public static ConcurrentHashMap<String, ScheduledFuture> runTasks = new ConcurrentHashMap<>(10);

    //线程池任务调度
    public static ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();

    @Autowired
    SchedulerXMapper schedulerXMapper;

    /**
     * 初始化线程池任务调度
     */
    @Autowired
    private SchedulerX2(){
        this.threadPoolTaskScheduler.setPoolSize(10);
        this.threadPoolTaskScheduler.setThreadNamePrefix("task-thread-");
        this.threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown(true);
        this.threadPoolTaskScheduler.initialize();
    }

    /**
     * 获取所有数据库里的定时任务
     */
    private void queryAllTaskDisp(){
        //查询所有，并put到tasks
        SchedulerX2.tasks.clear();
        List<TaskDisp> list = schedulerXMapper.queryAllTaskDisp();
        list.forEach((task)-> SchedulerX2.tasks.put(task.getTaskDispID(),task));
    }

    public void startSchedulerX2(String taskDispID) {
        if (tasks.size() <= 0) {
            queryAllTaskDisp();
        }
        TaskDisp taskDisp = tasks.get(taskDispID);
        try {
            Class<?> calzz = Class.forName(taskDisp.getTaskDispClass());
            Runnable runnable = (Runnable) calzz.newInstance();
            CronTrigger cronTrigger = new CronTrigger(taskDisp.getTaskDispExpr());
            runTasks.put(taskDispID, Objects.requireNonNull(threadPoolTaskScheduler.schedule(runnable, cronTrigger)));
//            updateTaskDisp(taskDisp.getID(), taskDisp.getTaskDispID(), "01");
            logger.info("定时任务名称： {} 编号： {}  任务已启动", taskDisp.getTaskDispName(), taskDisp.getTaskDispNo());
        } catch (ClassNotFoundException |InstantiationException | IllegalAccessException e) {
            logger.info("定时任务名称： {} 编号： {}  任务启动失败", taskDisp.getTaskDispName(), taskDisp.getTaskDispNo());
            e.printStackTrace();
        }
    }

    public void stopSchedulerX2(String taskDispID){
        TaskDisp taskDisp = tasks.get(taskDispID);
        runTasks.get(taskDisp.getTaskDispID()).cancel(true);
        runTasks.remove(taskDisp.getTaskDispID());
        updateTaskDisp(taskDisp.getID(), taskDisp.getTaskDispID(), "02");
        logger.info("定时任务名称： {} 编号： {}  任务已停止", taskDisp.getTaskDispName(), taskDisp.getTaskDispNo());
    }

    private void updateTaskDisp(String ID, String taskDispID, String taskDispStatus) {
        TaskDisp taskDisp = new TaskDisp();
        taskDisp.setID(ID);
        taskDisp.setTaskDispID(taskDispID);
        taskDisp.setTaskDispStatus(taskDispStatus);
        taskDisp.setUpdateTime(new Date());
        schedulerXMapper.updateTaskDisp(taskDisp);
    }

}
